package main

import (
	"crud-panel/interal"
	"crud-panel/utils"
	"encoding/json"
	"fmt"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/widget"
	"reflect"
)

func renderHead() *fyne.Container {
	txt := widget.NewLabelWithStyle("goravel crud工具v1.0", fyne.TextAlignTrailing, fyne.TextStyle{Bold: false})
	return container.NewVBox(txt)
}

// 获取结构体字段的注释（comment）
func getFieldComment(t reflect.Type, fieldIndex int) string {
	field := t.Field(fieldIndex)
	tag := field.Tag.Get("comment")
	if tag == "" {
		return field.Name // 如果没有 comment 标签，则返回字段名
	}
	return tag
}

func makeTable(myWindow fyne.Window) fyne.CanvasObject {
	client := interal.NewClient()
	err, response := client.GetTables()
	if err != nil {
		handleError(err, myWindow)
		return nil
	}
	res := response.Body()
	var resp utils.TableInfoResp
	if err := json.Unmarshal(res, &resp); err != nil {
		handleError(err, myWindow)
		return nil
	}

	// 获取列数，通过反射
	tableInfoType := reflect.TypeOf(utils.TableInfo{})
	colCount := tableInfoType.NumField()

	// 创建表头数据
	headers := make([]string, colCount+1) // 新增一列用于操作按钮
	for i := 0; i < colCount; i++ {
		headers[i] = getFieldComment(tableInfoType, i)
	}
	headers[colCount] = "操作" // 添加操作列

	// 创建表格
	list := widget.NewTable(
		func() (int, int) {
			// 获取行数，包括表头
			rowCount := len(resp.Data) + 1
			return rowCount, colCount + 1
		},
		func() fyne.CanvasObject {
			// 对于最后一列，创建按钮；对于其他列，创建标签
			if list.ColumnCount() > 0 && list.ColumnCount()-1 == colCount {
				return widget.NewButton("", nil)
			}
			label := widget.NewLabel("")
			label.Resize(fyne.NewSize(0, 40))
			return label
		},
		func(i widget.TableCellID, o fyne.CanvasObject) {
			if i.Row == 0 { // 表头
				o.(*widget.Label).SetText(headers[i.Col])
				return
			}

			if i.Col == colCount { // 操作按钮列
				btn := o.(*widget.Button)
				btn.SetText("操作")
				btn.OnTapped = func() {
					// 点击按钮后执行的操作，这里以打开新窗口为例
					openNewWindow(myWindow, i.Row-1, resp.Data) // 跳过表头行
				}
				return
			}

			// 处理数据行
			rowData := reflect.ValueOf(resp.Data[i.Row-1]) // 跳过表头行
			if i.Col >= rowData.NumField() {
				return
			}
			field := rowData.Field(i.Col)
			o.(*widget.Label).SetText(fmt.Sprintf("%v", field.Interface()))
		})

	// 设置每一列的最小宽度
	for i := 0; i < colCount+1; i++ {
		list.SetColumnWidth(i, 150) // 设置列宽为150
	}

	// 使用 MaxLayout 确保表格可以扩展到最大可用空间
	tableContainer := container.New(layout.NewMaxLayout(), list)

	// 将表格放入滚动容器中，支持水平和垂直滚动
	scrollContainer := container.NewScroll(tableContainer)

	// 设置滚动容器的最大高度，并让其根据内容自动调整宽度
	maxHeight := float32(400) // 设置最大高度
	minWidth := float32(600)  // 设置最小宽度
	scrollContainer.Resize(fyne.NewSize(minWidth, maxHeight))

	return scrollContainer
}

// 打开新的窗口
func openNewWindow(parent fyne.Window, rowIndex int, data []utils.TableInfo) {
	newApp := app.New()
	newWindow := newApp.NewWindow("操作窗口")

	// 可以在这里自定义新窗口的内容，例如显示所选行的数据
	content := container.NewVBox(
		widget.NewLabel(fmt.Sprintf("这是第 %d 行的数据操作界面", rowIndex+1)),
		widget.NewButton("关闭", func() {
			newWindow.Close()
		}),
	)

	newWindow.SetContent(content)
	newWindow.Resize(fyne.NewSize(400, 300))
	newWindow.Show()
}

func handleError(err error, myWindow fyne.Window) {
	dialog.ShowError(err, myWindow)
}

func main() {
	myApp := app.New()
	myWindow := myApp.NewWindow("crud工具v1.0")
	header := renderHead()
	table := makeTable(myWindow)

	// 使用 BorderLayout 让表格填充主要空间
	c := container.NewBorder(header, nil, nil, nil, table)

	myWindow.SetContent(c)
	// 设置一个合适的初始窗口大小
	myWindow.Resize(fyne.NewSize(800, 600))
	myWindow.ShowAndRun()
}
